home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
games
/
larn12s.arc
/
LARN.ARC
/
MONSTER.C
< prev
next >
Wrap
C/C++ Source or Header
|
1987-10-28
|
44KB
|
1,426 lines
/*
* monster.c Larn is copyrighted 1986 by Noah Morgan.
*
* This file contains the following functions:
* ----------------------------------------------------------------------------
*
* createmonster(monstno) Function to create a monster next to the player
* int monstno;
*
* int cgood(x,y,itm,monst) Function to check location for emptiness
* int x,y,itm,monst;
*
* createitem(it,arg) Routine to place an item next to the player
* int it,arg;
*
* cast() Subroutine called by parse to cast a spell for the user
*
* speldamage(x) Function to perform spell functions cast by the player
* int x;
*
* loseint() Routine to decrement your int (intelligence) if > 3
*
* isconfuse() Routine to check to see if player is confused
*
* nospell(x,monst) Routine to return 1 if a spell doesn't affect a monster
* int x,monst;
*
* fullhit(xx) Function to return full damage against a monst (aka web)
* int xx;
*
* direct(spnum,dam,str,arg) Routine to direct spell damage 1 square in 1 dir
* int spnum,dam,arg;
* char *str;
*
* godirect(spnum,dam,str,delay,cshow) Function to perform missile attacks
* int spnum,dam,delay;
* char *str,cshow;
*
* ifblind(x,y) Routine to put "monster" or the monster name into lastmosnt
* int x,y;
*
* tdirect(spnum) Routine to teleport away a monster
* int spnum;
*
* omnidirect(sp,dam,str) Routine to damage all monsters 1 square from player
* int sp,dam;
* char *str;
*
* dirsub(x,y) Routine to ask for direction, then modify x,y for it
* int *x,*y;
*
* vxy(x,y) Routine to verify/fix (*x,*y) for being within bounds
* int *x,*y;
*
* dirpoly(spnum) Routine to ask for a direction and polymorph a monst
* int spnum;
*
* hitmonster(x,y) Function to hit a monster at the designated coordinates
* int x,y;
*
* hitm(x,y,amt) Function to just hit a monster at a given coordinates
* int x,y,amt;
*
* hitplayer(x,y) Function for the monster to hit the player from (x,y)
* int x,y;
*
* dropsomething(monst) Function to create an object when a monster dies
* int monst;
*
* dropgold(amount) Function to drop some gold around player
* int amount;
*
* something(level) Function to create a random item around player
* int level;
*
* newobject(lev,i) Routine to return a randomly selected new object
* int lev,*i;
*
* spattack(atckno,xx,yy) Function to process special attacks from monsters
* int atckno,xx,yy;
*
* checkloss(x) Routine to subtract hp from user and flag bottomline display
* int x;
*
* annihilate() Routine to annihilate monsters around player, playerx,playery
*
* newsphere(x,y,dir,lifetime) Function to create a new sphere of annihilation
* int x,y,dir,lifetime;
*
* rmsphere(x,y) Function to delete a sphere of annihilation from list
* int x,y;
*
* sphboom(x,y) Function to perform the effects of a sphere detonation
* int x,y;
*
* genmonst() Function to ask for monster and genocide from game
*
*/
#include "header.h"
struct isave /* used for altar reality */
{
char type; /* 0=item, 1=monster */
char id; /* item number or monster number */
short arg; /* the type of item or hitpoints of monster */
};
/*
* createmonster(monstno) Function to create a monster next to the player
* int monstno;
*
* Enter with the monster number (1 to MAXMONST+8)
* Returns no value.
*/
createmonster(mon)
int mon;
{
register int x,y,k,i;
if (mon<1 || mon>MAXMONST+8) /* check for monster number out of bounds */
{
beep(); lprintf("\ncan't createmonst(%d)\n",(long)mon); nap(3000); return;
}
while (monster[mon].genocided && mon<MAXMONST) mon++; /* genocided? */
for (k=rnd(8), i= -8; i<0; i++,k++) /* choose direction, then try all */
{
if (k>8) k=1; /* wraparound the diroff arrays */
x = playerx + diroffx[k]; y = playery + diroffy[k];
if (cgood(x,y,0,1)) /* if we can create here */
{
mitem[x][y] = mon;
hitp[x][y] = monster[mon].hitpoints;
# ifdef DGK
stealth[x][y]=0;
know[x][y] &= ~KNOWHERE;
# else
stealth[x][y]=know[x][y]=0;
# endif
switch(mon)
{
case ROTHE: case POLTERGEIST: case VAMPIRE: stealth[x][y]=1;
};
return;
}
}
}
/*
* int cgood(x,y,itm,monst) Function to check location for emptiness
* int x,y,itm,monst;
*
* Routine to return TRUE if a location does not have itm or monst there
* returns FALSE (0) otherwise
* Enter with itm or monst TRUE or FALSE if checking it
* Example: if itm==TRUE check for no item at this location
* if monst==TRUE check for no monster at this location
* This routine will return FALSE if at a wall or the dungeon exit on level 1
*/
int cgood(x,y,itm,monst)
register int x,y;
int itm,monst;
{
if ((y>=0) && (y<=MAXY-1) && (x>=0) && (x<=MAXX-1)) /* within bounds? */
if (item[x][y]!=OWALL) /* can't make anything on walls */
if (itm==0 || (item[x][y]==0)) /* is it free of items? */
if (monst==0 || (mitem[x][y]==0)) /* is it free of monsters? */
if ((level!=1) || (x!=33) || (y!=MAXY-1)) /* not exit to level 1 */
return(1);
return(0);
}
/*
* createitem(it,arg) Routine to place an item next to the player
* int it,arg;
*
* Enter with the item number and its argument (iven[], ivenarg[])
* Returns no value, thus we don't know about createitem() failures.
*/
createitem(it,arg)
int it,arg;
{
register int x,y,k,i;
if (it >= MAXOBJ) return; /* no such object */
for (k=rnd(8), i= -8; i<0; i++,k++) /* choose direction, then try all */
{
if (k>8) k=1; /* wraparound the diroff arrays */
x = playerx + diroffx[k]; y = playery + diroffy[k];
if (cgood(x,y,1,0)) /* if we can create here */
{
item[x][y] = it; know[x][y]=0; iarg[x][y]=arg; return;
}
}
}
/*
* cast() Subroutine called by parse to cast a spell for the user
*
* No arguments and no return value.
*/
static char eys[] = "\nEnter your spell: ";
cast()
{
register int i,j,a,b,d;
cursors();
if (c[SPELLS]<=0) { lprcat("\nYou don't have any spells!"); return; }
lprcat(eys); --c[SPELLS];
while ((a=getchar())=='D')
{ seemagic(-1); cursors(); lprcat(eys); }
if (a=='\33') goto over; /* to escape casting a spell */
if ((b=getchar())=='\33') goto over; /* to escape casting a spell */
if ((d=getchar())=='\33')
{ over: lprcat(aborted); c[SPELLS]++; return; } /* to escape casting a spell */
#ifdef EXTRA
c[SPELLSCAST]++;
#endif
for (lprc('\n'),j= -1,i=0; i<SPNUM; i++) /*seq search for his spell, hash?*/
if ((spelcode[i][0]==a) && (spelcode[i][1]==b) && (spelcode[i][2]==d))
if (spelknow[i])
{ speldamage(i); j = 1; i=SPNUM; }
if (j == -1) lprcat(" Nothing Happened ");
bottomline();
}
/*
* speldamage(x) Function to perform spell functions cast by the player
* int x;
*
* Enter with the spell number, returns no value.
* Please insure that there are 2 spaces before all messages here
*/
speldamage(x)
int x;
{
register int i,j,clev;
int xl,xh,yl,yh;
register char *p,*kn,*pm;
if (x>=SPNUM) return; /* no such spell */
if (c[TIMESTOP]) { lprcat(" It didn't seem to work"); return; } /* not if time stopped */
clev = c[LEVEL];
if ((rnd(23)==7) || (rnd(18) > c[INTELLIGENCE]))
{ lprcat(" It didn't work!"); return; }
if (clev*3+2 < x) { lprcat(" Nothing happens. You seem inexperienced at this"); return; }
switch(x)
{
/* ----- LEVEL 1 SPELLS ----- */
case 0: if (c[PROTECTIONTIME]==0) c[MOREDEFENSES]+=2; /* protection field +2 */
c[PROTECTIONTIME] += 250; return;
case 1: i = rnd(((clev+1)<<1)) + clev + 3;
godirect(x,i,(clev>=2)?" Your missiles hit the %s":" Your missile hit the %s",100,'+'); /* magic missile */
return;
case 2: if (c[DEXCOUNT]==0) c[DEXTERITY]+=3; /* dexterity */
c[DEXCOUNT] += 400; return;
case 3: i=rnd(3)+1;
p=" While the %s slept, you smashed it %d times";
ws: direct(x,fullhit(i),p,i); /* sleep */ return;
case 4: /* charm monster */